package com.binhthuan.catechist.server.service;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.binhthuan.catechist.server.ErrorObject;
import com.binhthuan.catechist.server.ResponseObject;
import com.binhthuan.catechist.server.bus.GradeBUS;
import com.binhthuan.catechist.server.domain.Grade;
import com.binhthuan.catechist.server.domain.Trainer;
import com.binhthuan.catechist.shared.constant.Parameter;

public class GradeServlet extends AbstractServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    protected void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        addGrade(request, response);
    }

    @Override
    protected void fetch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if (request.getParameter(Parameter.ID) != null) {
            getGradeById(request, response);
        } else {
            getAllGrades(request, response);
        }
    }

    @Override
    protected void remove(HttpServletRequest request, HttpServletResponse response, boolean confirmation)
            throws ServletException, IOException {
        deleteGrade(request, response, confirmation);
    }

    @Override
    protected void update(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {
        updateGrade(request, response);
    }

    private void addGrade(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String name = request.getParameter(Parameter.NAME);
        String leaderIdString = request.getParameter(Parameter.LEADER);

        try {
            Grade grade = new Grade();
            grade.setName(name);

            GradeBUS bus = new GradeBUS();
            if (bus.getGradeByName(name.trim()) != null) {
                ErrorObject error = new ErrorObject(STATUS_VALIDATION_ERROR);
                error.addError(Parameter.NAME, getMessagesFactory().duplicatedName());
                sendResponse(error.toJson());
                return;
            }

            if (leaderIdString != null) {
                int leaderId = Integer.parseInt(leaderIdString);
                Trainer leader = new Trainer();
                leader.setId(leaderId);

                grade.setLeader(leader);
            }

            if (bus.save(grade)) {
                sendResponse(new ResponseObject(grade).toJson());
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void getGradeById(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String id = request.getParameter(Parameter.ID);

        try {
            int gradeId = Integer.parseInt(id);

            GradeBUS bus = new GradeBUS();
            Grade grade = bus.getGradeById(gradeId);

            sendResponse(new ResponseObject(grade).toJson());
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void getAllGrades(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            GradeBUS bus = new GradeBUS();
            List<Grade> grades = bus.getAllGrades();

            sendResponse(new ResponseObject(grades).toJson());
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void deleteGrade(HttpServletRequest request, HttpServletResponse response, boolean confirmation) throws IOException {
        String gradeId = request.getParameter(Parameter.ID);
        try {
            int id = Integer.parseInt(gradeId);

            GradeBUS bus = new GradeBUS();
            if (bus.isInUsed(id) && !confirmation) {
                ErrorObject error = new ErrorObject(STATUS_VALIDATION_ERROR);
                error.addError(Parameter.NAME, getMessagesFactory().itemIsInUsed("\"" + bus.getGradeById(id).getName() + "\""));
                error.setRequireConfirmation(true);
                sendResponse(error.toJson());
                return;
            }

            if (bus.deleteGrade(id)) {
                sendResponse(new ResponseObject((Object) null).toJson());
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void updateGrade(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String gradeId = request.getParameter(Parameter.ID);
        String name = request.getParameter(Parameter.NAME);
        String leaderIdString = request.getParameter(Parameter.LEADER);

        try {
            int id = Integer.parseInt(gradeId);

            GradeBUS bus = new GradeBUS();
            Grade currentGrade = bus.getGradeByName(name.trim());  
            if (currentGrade != null && currentGrade.getId() != id) {
                ErrorObject error = new ErrorObject(STATUS_VALIDATION_ERROR);
                error.addError(Parameter.NAME, getMessagesFactory().duplicatedName());
                sendResponse(error.toJson());
                return;
            }

            currentGrade = bus.getGradeById(id);
            currentGrade.setName(name);

            if (leaderIdString != null) {
                int leaderId = Integer.parseInt(leaderIdString);
                Trainer leader = new Trainer();
                leader.setId(leaderId);

                currentGrade.setLeader(leader);
            }

            if (bus.save(currentGrade)) {
                sendResponse(new ResponseObject(currentGrade).toJson());
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }
}
